
function Fly(behaviour) {
	this.initFly(behaviour);
}
Fly.prototype={
	wings:'c',
	speed:50,
        wingSpeed:50,
	angle:0,
	x:0,
	y:0,
	size:60,
	isMoving:false,
	interval:null,
	img:null,

	initFly:function(behaviour) {
		if (typeof(Flies)=='undefined') Flies=new Array();
		this.index=Flies.length;
		Flies[this.index]=this;
		if (behaviour) {
			this.Behaviour=behaviour;
			behaviour.SetFly(this);
		} else
			this.Behaviour=new DefaultFlyBehaviour(this);
		this.img=this.GetImage();
		this.SetPosition(Math.random()*this.maxWidth(),Math.random()*this.maxHeight());
		this.SetAngle(Math.random()*360);
		this.Refresh();
	},

	IsMoving:function() { return this.isMoving; },
	SetMoving:function(val) {
		this.isMoving=val;
		if (this.interval!=null) clearInterval(this.interval);
		if (val) this.interval=setInterval("Flies["+this.index+"].MoveIt()",this.wingSpeed);
			else this.CloseWings();
	},
	SetSize:function(size) {
		this.size=size;
		this.Refresh();
	},
	MoveIt:function() {
		switch(this.wings) {
			case 'c':
				this.OpenWings();
				break;
			case 'o':
				this.CloseWings();
				break;
		}
		this.SetPosition(this.x+Math.cos(this.angle*Math.PI/180)*1500/this.speed,this.y+Math.sin(this.angle*Math.PI/180)*1500/this.speed);
		if (this.Behaviour&&this.Behaviour.Behave)
			this.Behaviour.Behave();
	},
	OpenWings:function() {
		this.wings='o';
		this.Refresh();
	},
	CloseWings:function() {
		this.wings='c';
		this.Refresh();
	},
	GetImageName:function(index) {
		if (index==null) {
			imageAngle=Math.round(this.angle/45.0)*45;
			while (imageAngle>=360) imageAngle-=360;
			var imageName=this.wings+imageAngle;
		} else {
			var imageName=index;
		}
		switch(imageName) {
			case 'c0':
				imageName=
'http://4.bp.blogspot.com/_6GyQjwWOmQA/Rlm3LTjHqPI/AAAAAAAAAE8/N-TMYI5KAPM/s400/c0.gif'
				break;
			case 'c45':
				imageName=
'http://1.bp.blogspot.com/_6GyQjwWOmQA/Rlm3wjjHqQI/AAAAAAAAAFE/rqi3_0J6MMA/s400/c45.gif'
				break;
			case 'c90':
				imageName=
'http://2.bp.blogspot.com/_6GyQjwWOmQA/Rlm37zjHqRI/AAAAAAAAAFM/TJHTolQXCzA/s400/c90.gif'
				break;
			case 'c135':
				imageName=
'http://2.bp.blogspot.com/_6GyQjwWOmQA/Rlm4FzjHqSI/AAAAAAAAAFU/fOeLko03HgM/s400/c135.gif'
				break;
			case 'c180':
				imageName=
'http://2.bp.blogspot.com/_6GyQjwWOmQA/Rlm4QzjHqTI/AAAAAAAAAFc/DFxrFkZF8_8/s400/c180.gif'
				break;
			case 'c225':
				imageName=
'http://2.bp.blogspot.com/_6GyQjwWOmQA/Rlm4kzjHqUI/AAAAAAAAAFk/Fr9GqQB_YnA/s400/c225.gif'
				break;
			case 'c270':
				imageName=
'http://1.bp.blogspot.com/_6GyQjwWOmQA/Rlm4vjjHqVI/AAAAAAAAAFs/XXJjb8suHSw/s400/c270.gif'
				break;
			case 'c315':
				imageName=
'http://2.bp.blogspot.com/_6GyQjwWOmQA/Rlm46zjHqWI/AAAAAAAAAF0/CrCjDpSrDTs/s400/c315.gif'
				break;
			case 'o0':
				imageName=
'http://4.bp.blogspot.com/_6GyQjwWOmQA/Rlm5FTjHqXI/AAAAAAAAAF8/ZCMq80HNoHM/s400/o0.gif'
				break;
			case 'o45':
				imageName=
'http://4.bp.blogspot.com/_6GyQjwWOmQA/Rlm5PTjHqYI/AAAAAAAAAGE/wJVsgAC5Tzk/s400/o45.gif'
				break;
			case 'o90':
				imageName=
'http://3.bp.blogspot.com/_6GyQjwWOmQA/Rlm5YDjHqZI/AAAAAAAAAGM/5eqN6CVYXVc/s400/o90.gif'
				break;
			case 'o135':
				imageName=
'http://2.bp.blogspot.com/_6GyQjwWOmQA/Rlm5mzjHqaI/AAAAAAAAAGU/CjDKSrg9GtI/s400/o135.gif'
				break;
			case 'o180':
				imageName=
'http://4.bp.blogspot.com/_6GyQjwWOmQA/Rlm5wTjHqbI/AAAAAAAAAGc/Nir8gvXq09M/s400/o180.gif'
				break;
			case 'o225':
				imageName=
'http://3.bp.blogspot.com/_6GyQjwWOmQA/Rlm56DjHqcI/AAAAAAAAAGk/zZmoUGZZvSQ/s400/o225.gif'
				break;
			case 'o270':
				imageName=
'http://2.bp.blogspot.com/_6GyQjwWOmQA/Rlm6DzjHqdI/AAAAAAAAAGs/SUewvqZUHWs/s400/o270.gif'
				break;
			case 'o315':
				imageName=
'http://2.bp.blogspot.com/_6GyQjwWOmQA/Rlm64zjHqeI/AAAAAAAAAG0/z7i_0jxCAzs/s400/o315.gif'
				break;
		}
		return imageName;
	},
	GetImage:function() {
		if (!this.images) {
			this.images=new Array();
			for (var a=0; a<360; a+=45) {
				var img=document.createElement('img');
				img.fly=this;
				img.src=this.GetImageName('c'+a);
				img.style.position='absolute';
				img.style.display='none';
				img.onmouseover=function() {this.fly.OnMouseOver();};
				img.onclick=function() {this.fly.OnClick();};
				img.title="I know what the disease wants";
				document.body.appendChild(img);
				this.images['c'+a]=img;
			}
			for (var a=0; a<360; a+=45) {
				var img=document.createElement('img');
				img.fly=this;
				img.src=this.GetImageName('o'+a);
				img.style.position='absolute';
				img.style.display='none';
				img.onmouseover=function() {this.fly.OnMouseOver();};
				img.onclick=function() {this.fly.OnClick();};
				img.title="I know what the disease wants";
				document.body.appendChild(img);
				this.images['o'+a]=img;
			}
		}
		var imageAngle=Math.round(this.angle/45.0)*45;
		while (imageAngle>=360) imageAngle-=360;
		var imageName=this.wings+imageAngle;
		return this.images[imageName];
	},
	Refresh:function() {
		var prevImg=this.img;
		if (prevImg!=null) prevImg.style.display='none';
		this.img=this.GetImage();
		this.img.style.display='';
		this.img.style.left=this.x+'px';
		this.img.style.top=this.y+'px';
		this.img.style.width=this.size+'px';
		this.img.style.height=this.size+'px';
	},
	SetAngle:function(val) {
		this.angle=parseInt(val);
		while (this.angle<0) this.angle+=360;
		while (this.angle>=360) this.angle-=360;
		this.Refresh();
	},
	SetSpeed:function(val) {
		this.speed=parseInt(val);
		this.Refresh();
	},
	maxHeight:function() {
		var h=0;
		if (window.document.innerHeight>h) h=window.document.innerHeight;
		if (window.document.documentElement.clientHeight>h) h=window.document.documentElement.clientHeight;
		if (window.document.body.clientHeight>h) h=window.document.body.clientHeight;
		return h;
	},
	maxWidth:function() {
		var w=0;
		if (window.document.innerWidth>w) w=window.document.innerWidth;
		if (window.document.documentElement.clientWidth>w) w=window.document.documentElement.clientWidth;
		if (window.document.body.clientWidth>w) w=window.document.body.clientWidth;
		return w;
	},
	SetPosition:function(x,y) {
		var horizontal_overflow=0;
		var vertical_overflow=0;
		this.x=parseInt(x);
		this.y=parseInt(y);
		if (this.x<0) {
			this.x=0;
			horizontal_overflow=-1;
		}
		if (this.y<0) {
			this.y=0;
			vertical_overflow=-1;
		}
		if (this.img&&(this.x>=this.maxWidth()-this.img.clientWidth)) {
			this.x=this.maxWidth()-this.img.clientWidth-1;
			horizontal_overflow=1;
		}
		if (this.img&&(this.y>=this.maxHeight()-this.img.clientHeight)) {
			this.y=this.maxHeight()-this.img.clientHeight-1;
			vertical_overflow=1;
		}
		if (this.Behaviour&&this.Behaviour.OnHit)
			this.Behaviour.OnHit(horizontal_overflow,vertical_overflow);
		this.Refresh();
	},
	OnMouseOver:function() {
		if (this.Behaviour&&this.Behaviour.OnMouseOver)
			this.Behaviour.OnMouseOver();
	},
	OnClick:function() {
		if (this.Behaviour&&this.Behaviour.OnClick)
			this.Behaviour.OnClick();
	}
}

function DefaultFlyBehaviour(fly) {
	this.initBehaviour(fly);
}
DefaultFlyBehaviour.prototype={
	fly:null,
	bothered:0,
	initBehaviour:function(fly) {
		this.SetFly(fly);
	},
	SetFly:function(fly) {
		this.fly=fly;
	},
	Behave:function() {
		if (!this.fly) return;
		if (this.bothered>0) this.bothered--;
		   else this.fly.SetMoving(false);
		if (Math.random()*15<2) this.TurnRandomly();
	},
	TurnRandomly:function() {
		if (!this.fly) return;
		if (!this.lastTurn||Math.random()*3>2) this.lastTurn=
			Math.round(Math.random()*20+35)*(parseInt(Math.random()*2)*2-1);
		this.fly.SetAngle(this.fly.angle+this.lastTurn);
	},
	OnHit:function(ho,vo) {
		if (!this.fly) return;
		switch(ho) {
			case -1:
				if (this.fly.angle>90 && this.fly.angle<270) this.TurnRandomly();
				break;
			case 1:
				if (this.fly.angle<90 || this.fly.angle>270) this.TurnRandomly();
				break;
		}
		switch(vo) {
			case -1:
				if (this.fly.angle>180) this.TurnRandomly();
				break;
			case 1:
				if (this.fly.angle>0 && this.fly.angle<180) this.TurnRandomly();
				break;
		}
	},
	OnMouseOver:function() {
		this.bothered+=50;
		this.fly.SetMoving(true);
	},
	OnClick:function() {}
}

function SexualFlyBehaviour(fly) {
	this.initBehaviour(fly);
}
var sfb=new DefaultFlyBehaviour();
sfb.DefaultOnHit=sfb.OnHit;
sfb.OnHit=function(ho,vo) {
	this.DefaultOnHit(ho,vo);
	if ((Flies.length>1)&&(ho==0)&&(vo==0)) {
		if (!this.mate&&(Math.random()*100<1))
			this.FindMate();
		if (this.mate) {
			var dy=this.mate.y-this.fly.y;
			var dx=this.mate.x-this.fly.x;
			if (Math.random()*100<3) {
				var ang=Math.atan2(dy,dx);
				this.fly.SetAngle(180/Math.PI*ang);
			}
			if (dx*dx+dy*dy < this.fly.size*this.mate.size)
				this.Mate();
			if (Math.random()*100 < 2) this.FindMate();
			if (Math.random()*1000 < 8) this.mate=null;
		}
	}
}
sfb.FindMate=function() {
	this.mate=null;
	while (!this.mate||(this.mate.index==this.fly.index))
		this.mate=Flies[Math.floor(Math.random()*Flies.length)];
}
sfb.Mate=function() {
	if (!Flies.MaxFlies) Flies.MaxFlies=10;
	if (Flies.length>=Flies.MaxFlies) return;
	var f=new Fly(new SexualFlyBehaviour());
	f.x=(this.fly.x+this.mate.x)/2;
	f.y=(this.fly.y+this.mate.y)/2;
	f.speed=(this.fly.speed+this.mate.speed)/2;
	f.Behaviour.bothered=100;
	f.SetMoving(true);
	f.SetSize((this.fly.size+this.mate.size)/2);
	this.mate=null;
}
SexualFlyBehaviour.prototype=sfb;
